package com.region.http.client.request.apcache;

import com.region.common.adapter.logging.LoggerAdapter;
import com.region.common.adapter.logging.LoggerAdapterFactory;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.protocol.HttpContext;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

/**
 * common http request retry handler
 *
 * @author liujieyu
 * @date 2022/12/16 19:27
 */
public class CommonHttpRequestRetryHandler implements HttpRequestRetryHandler {

    private static final LoggerAdapter logger = LoggerAdapterFactory.getLogger(CommonHttpRequestRetryHandler.class);

    @Override
    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
        if (executionCount > 1) {
            logger.error("retry has more than 1 time, give up request");
            return false;
        }
        if (exception instanceof NoHttpResponseException) {
            logger.error("receive no response from server, retry", exception);
            return true;
        }
        if (exception instanceof SSLHandshakeException) {
            logger.error("SSL hand shake exception", exception);
            return false;
        }
        if (exception instanceof InterruptedIOException) {
            logger.error("InterruptedIOException", exception);
            return false;
        }
        if (exception instanceof UnknownHostException) {
            logger.error("server host unknown", exception);
            return false;
        }
        if (exception instanceof ConnectTimeoutException) {
            logger.error("Connection Time out", exception);
            return false;
        }
        if (exception instanceof SSLException) {
            logger.error("SSLException");
            return false;
        }
        HttpClientContext httpClientContext = HttpClientContext.adapt(context);
        HttpRequest request = httpClientContext.getRequest();
        if (!(request instanceof HttpEntityEnclosingRequest)) {
            return true;
        }
        return false;
    }
}
